const mqtt = require('/utils/4.1.0/mqtt.min')
const { Random } = require("random-js");
App({

    /**
     * 当小程序初始化完成时，会触发 onLaunch（全局只触发一次）
     */
    onLaunch: function () {
        console.log("App onLaunch");
    },

    /**
     * 当小程序启动，或从后台进入前台显示，会触发 onShow
     */
    onShow: function (options) {
        const {miniProgram: {envVersion}} = wx.getAccountInfoSync()
        console.log(`App onShow envVersion ${envVersion}`);
        this.connectMqtt()
    },

    /**
     * 当小程序从前台进入后台，会触发 onHide
     */
    onHide: function () {
        console.log("App onHide");
        this.disConnectMqtt()
    },

    /**
     * 当小程序发生脚本错误，或者 api 调用失败时，会触发 onError 并带上错误信息
     */
    onError: function (msg) {
        console.log("App onError", msg);
    },
    data: {
        mqttClient: null,
        envVersion: null,
        subTopics: [],
        brokerUrl: 'wxs://test.ironmanapi.com:8084/mqtt',
        options: {
            clientId: "sabre_" + new Random().string(6).toLocaleLowerCase(),
            username: "admin",
            password: "nttieren0513",
            keepalive: 5
        }
    },
    connectMqtt() {
        this.data.mqttClient = mqtt.connect(this.data.brokerUrl, this.data.options)
        this.data.mqttClient.on('connect', () => {
            console.log(`connectMqtt clientId [${this.data.options.clientId}] connect success`)
            wx.showToast({
                title: 'EMQ连接成功',
                icon: "none",
                mask: true,
                duration: 1000
            })
            this.reSubscribe()
        })
        this.data.mqttClient.on('reconnect', () => {
            console.log('reconnect')
        })
        this.data.mqttClient.on('close', () => {
            console.log('close')
        })
        this.data.mqttClient.on('disconnect', packet => {
            console.log('disconnect', packet)
        })
        this.data.mqttClient.on('offline', () => {
            console.log('offline')
        })
        this.data.mqttClient.on('error', e => {
            console.log('error', e)
        })
        this.data.mqttClient.on('end', () => {
            console.log('end')
        })
    },
    disConnectMqtt() {
        this.data.mqttClient.end(true)
        console.log("mqtt client end")
    },
    reSubscribe() {
        if (this.data.subTopics.length) {
            const topic0 = this.data.subTopics.filter(subTopic => subTopic.qos === 0).map(item => item.topic);
            const sub0 = this.subscribe(topic0, 0)
            const topic1 = this.data.subTopics.filter(subTopic => subTopic.qos === 1).map(item => item.topic);
            const sub1 = this.subscribe(topic1, 1)
            const topic2 = this.data.subTopics.filter(subTopic => subTopic.qos === 2).map(item => item.topic);
            const sub2 = this.subscribe(topic2, 2);
            Promise.all([sub0, sub1, sub2]).then(res => {
                wx.showToast({
                    title: '重新订阅成功',
                    icon: "none",
                    mask: true,
                    duration: 1000
                })
                console.log(`clientId ${this.data.options.clientId} finish reSubscribe`)
            }).catch(err => {
                wx.showToast({
                    title: '重新订阅失败',
                    icon: "none",
                    mask: true,
                    duration: 1000
                })
            })
        }
    },
    subscribe(topics, qos) {
        return new Promise((resolve, reject) => {
            if (!topics || topics.length === 0) {
                resolve()
            }
            const client = this.data.mqttClient
            client.subscribe(topics, {qos}, err => {
                if (!err) {
                    topics.forEach(topic => {
                        if (!this.data.subTopics.some(item => item.topic === topic)) {
                            this.data.subTopics.push({topic, qos})
                        }
                    });
                    resolve()
                }
                reject(err)
            })
        })
    },
    unSubscribe(topics) {
        return new Promise((resolve, reject) => {
            const client = this.data.mqttClient
            client.unsubscribe(topics, err => {
                if (!err) {
                    topics.forEach((element, index) => {
                        const findIndex = this.data.subTopics.findIndex(item => item.topic === element);
                        if (findIndex !== -1) {
                            this.data.subTopics.splice(findIndex, 1);
                        }
                    });
                    resolve()
                }
                reject(err)
            })
        })
    }
})
